package cc.rengu.igas.mcps.core.realize.impl;
/*
 *Create by fuyp on 2020-3-28
 * 1:完成pos的基础的公共安全校验，mac验签，地理位置校验，sn校验，签到校验，
 * 2:终端状态校验，商户状态校验，商户业务权限，终端业务权限校验。
 * 3:商户退款的相关的公共校验
 */

import cc.rengu.igas.mcps.common.constant.McpsTreeNodeConstant;
import cc.rengu.igas.mcps.common.constant.McpsTxnNumConstant;
import cc.rengu.igas.mcps.common.dao.TermKeyMapper;
import cc.rengu.igas.mcps.common.dao.impl.TermKeyMapperImpl;
import cc.rengu.igas.mcps.common.entity.TermKey;
import cc.rengu.igas.mcps.common.enums.KeyTypeEnum;
import cc.rengu.igas.mcps.common.enums.RespCodeEnum;
import cc.rengu.igas.mcps.core.realize.PosPublicCheckService;
import cc.rengu.igas.mcps.core.realize.TermService;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntAuthInfo;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.MchntKeyInfo;
import cc.rengu.igas.share.core.model.MchntTermInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.PayOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.PayOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.TxnInfoService;
import cc.rengu.oltp.service.realize.impl.TxnInfoServiceImpl;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PosPublicCheckServiceImpl implements PosPublicCheckService {
    private final RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    /*
     * 公共校验pos的基础的公共安全校验，mac验签，地理位置校验，sn校验，签到校验，
     * */
    @Override
    public void posPublicCheckService() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        String termNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_NO);
        String instId = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.INST_ID);

        /*终端状态和签到校验*/
        TermService termService = new TermServiceImpl();
        MchntTermInfo mchntTermInfo = termService.checkTermInfo(instId, mchntNo, termNo);

        /* 获取交易配置信息 */
        TxnInfo txnInfo = (TxnInfo) xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.TXN_INFO,TxnInfo.class);

        /* mac验签,根据交易是否验签判断 */
        if ("Y".equals(txnInfo.getSrcTxnAuthCfg().getSignFlag())) {
            /* 获取mac验签字符串(有联机平台组成需要验签字符串) */
            String signBlock = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SIGN_BLOCK);
            /* pos交易上送mac值 */
            TermKeyMapper termKeyMapper = new TermKeyMapperImpl();
            TermKey termKeyTmp = termKeyMapper.getTermKey(instId, mchntNo, termNo, KeyTypeEnum.TAK.getTypeCode());
            if (null == termKeyTmp) {
                rglog.error("未获取到签名密钥");
                throw new BizException(RespCodeEnum.POS_SIGN_ERROR.getRespCode(), RespCodeEnum.POS_SIGN_ERROR.getRespDesc());
            }
            xmlTreeUtil.setXmlTreeStringValue(KeyTypeEnum.TAK.name(), termKeyTmp.getKeyValue());

            String signature = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SIGNATURE);
            rglog.debug("验签字符串signBlock:{},pos上送signature:{}", signBlock, signature);
            /* 校验mac */
            if (!MD5Util.verifySignString(signature, signBlock, "&key=", termKeyTmp.getKeyValue())) {
                rglog.error("验签失败!sign:<{}>，signBlock:<{}>", signature, signBlock);
                throw new BizException(RespCodeEnum.POS_SIGN_ERROR.getRespCode(), RespCodeEnum.POS_SIGN_ERROR.getRespDesc());
            }
        }

        /* SN序列号校验 */
        String termSn = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SERIALL_NUM);
        if (StringUtil.isEmptyOrNull(termSn) || !mchntTermInfo.getTermSn().equals(termSn)) {
            /* 终端序列号验证失败 */
            rglog.error("终端上送SN序列号不正确");
            throw new BizException(RespCodeEnum.SN_CHECK_ERROR.getRespCode(), RespCodeEnum.SN_CHECK_ERROR.getRespDesc());
        }

        /* 判断地区代码、经纬度,主密钥下载不校验经纬度，更新终端经纬度 */
        if (!"M00MC006".equals(txnInfo.getSrcTxnAuthCfg().getTxnNum()) &&
                !StringUtil.isEmptyOrNull(mchntTermInfo.getLatitude()) && !StringUtil.isEmptyOrNull(mchntTermInfo.getLongitude())) {
            /* 终端地理位置、地理位置校验，经纬度校验 */
            String txnLatitude = xmlTreeUtil.getXmlTreeStringValue("termInfo/latitude");
            String txnLongitude = xmlTreeUtil.getXmlTreeStringValue("termInfo/longitude");
            termService.checkTermLocation(txnLatitude, txnLongitude, mchntTermInfo);
        } else {
            /* 校验地区代码 */
            String addrArea = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_ADDR_AREA);
            if (!StringUtil.isEmptyOrNull(addrArea) && !mchntTermInfo.getTermAreaCode().equals(addrArea)) {
                rglog.error("终端上送地区代码不正确");
                throw new BizException(RespCodeEnum.AREA_CHECK_ERROR.getRespCode(), RespCodeEnum.AREA_CHECK_ERROR.getRespDesc());
            }
        }
    }

    /*
     * 智能终端校验，校验商户状态、终端状态、商户秘钥
     * */
    @Override
    public void illtPublicCheckService() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        String instId = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.INST_ID);
        String signBlock = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SIGN_BLOCK);
        String sign = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.SIGN);
        TxnInfo txnInfo = (TxnInfo) xmlTreeUtil.getXmlTreeObjectValue(TreeNodeConstant.TXN_INFO, TxnInfo.class);

        /*商户秘钥验证，根据通讯设置标识判断是否验密，新平台对接商户通过开放平台接入，不需要验商户秘钥，老平台商户 */
        if ("Y".equals(txnInfo.getSrcTxnAuthCfg().getSignFlag())) {
            if (!verifyMchntSignString(instId, sign, signBlock, mchntNo)) {
                rglog.error("商户验签失败{}", mchntNo);
                throw new BizException(RespCodeEnum.ILLT_MCHNT_SIGN_ERROR.getRespCode(), RespCodeEnum.ILLT_MCHNT_SIGN_ERROR.getRespDesc());
            }
        }
    }

    /*
     * 终端状态校验，商户状态校验，商户业务权限，终端业务权限校验。
     * */
    @Override
    public void posPublicAuthCtrlCheckService(TxnInfo txnInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        String termNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_NO);
        String instId = txnInfo.getSrcTxnAuthCfg().getInstId();

        /*商户和终端业务权限检查 */
        String txnNum = txnInfo.getSrcTxnAuthCfg().getTxnNum();
        String bizType = txnInfo.getSrcTxnAuthCfg().getBizType();
        /* 公共基础业务权限不做校验 */
        if ("00".equals(txnInfo.getSrcTxnAuthCfg().getBizProdCode())) {
            rglog.info("公共基础产品不做商户业务权限校验:<{}>", txnNum);
            return;
        }

        /* 获取商户信息 */
        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("查询商户信息失败<{}>", mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }

        /*连锁门店 非独立清算商户 需要判断一级商户的业务权限*/
        String mchntNoTem = mchntNo;
        if (null != mchntInfo.getIndependentDataFlag()) {
            if ("11".equals(mchntInfo.getMchntType()) && "N".equals(mchntInfo.getIndependentDataFlag())) {
                mchntNoTem = mchntInfo.getChainMchntNo();
            }
        }
        /*检查商户业务权限*/
        List<MchntAuthInfo> mchntAuthInfoList = mchntService.getMchntAuthInfo(instId, mchntNo, termNo, txnNum, bizType);
        if (null == mchntAuthInfoList || mchntAuthInfoList.isEmpty()) {
            rglog.warn("未配置商户<{}>下终端<{}>的业务权限校验规则，校验商户是否有对应权限!", mchntNo, termNo);
            boolean checkResult = mchntService.checkMchntAuth(instId, mchntNoTem, null, txnNum, bizType, AcctTypeEnum.ALL.getAcctType());
            if (!checkResult) {
                rglog.error("商户号<{}>不支持此交易<{}>", mchntNoTem, txnNum);
                throw new BizException(RespCodeEnum.TERM_TXN_NOT_SUPPORT.getRespCode(), RespCodeEnum.TERM_TXN_NOT_SUPPORT.getRespDesc());
            }
        } else {
            MchntAuthInfo mchntAuthInfo = mchntAuthInfoList.get(0);
            if (AppParamConstant.NO.equals(mchntAuthInfo.getSupportFlag())) {
                rglog.error("商户<{}>下终端<{}>不支持此交易<{}>", mchntNoTem, termNo, txnNum);
                throw new BizException(RespCodeEnum.TERM_TXN_NOT_SUPPORT.getRespCode(), RespCodeEnum.TERM_TXN_NOT_SUPPORT.getRespDesc());
            }
        }
    }

    /*
     * 退款公共业务校验
     * 通过业务状态可以只取出消费金额，把撤销，冲正，退款交易和原支付交易以排除
     * 如果商户没有虚拟账户，并且是T+1清算
     * */
    @Override
    public void posPublicRefundCheckService() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String msgSrcId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID);
        String transChannelId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.CHANNEL_ID);

        /* Step1：获取原交易请求流水号或支付流水号 */
        String oriTraceNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.ORI_TRACE_NO);
        String oriPayId = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.ORI_PAY_ID);
        if (null == oriTraceNo && null == oriPayId) {
            rglog.error("交易报文未上送原交易请求流水号或支付流水号！");
            throw new BizException(RespCodeEnum.POS_FORMAT_ERROR.getRespCode(), RespCodeEnum.POS_FORMAT_ERROR.getRespDesc());
        }
        /* Step2：根据原请求流水或支付流水号查询原用户订单信息 */
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo oriUserOrderInfo;
        if (!StringUtil.isEmptyOrNull(oriTraceNo)) {
            oriUserOrderInfo = userOrderInfoMapper.selectUserOrderInfoByFrontSeqNum(instId, oriTraceNo, msgSrcId, transChannelId);
            if (null == oriUserOrderInfo) {
                oriUserOrderInfo = userOrderInfoMapper.selectUserOrderInfoByFrontSeqNum(instId, oriTraceNo, msgSrcId, "*");
                if (null == oriUserOrderInfo) {
                    rglog.error("原交易流水不存在!");
                    throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
                }
            }
        } else {
            oriUserOrderInfo = userOrderInfoMapper.selectUserOrderInfoByUserOrderId(instId, oriPayId);
            if (null == oriUserOrderInfo) {
                rglog.error("原交易流水不存在!");
                throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
            }
        }
        rglog.debug("打印用户订单记录状态orderStatus:<{}>,transStatus:<{}>,bizStatus<{}>", oriUserOrderInfo.getOrderStatus(), oriUserOrderInfo.getTransStatus(), oriUserOrderInfo.getBizStatus());
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_USER_ORDER_INFO, oriUserOrderInfo);

        /* Step2：根据原系统流水号原商户订单信息 */
        MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        List<MchntOrderInfo> oriMchntOrderInfoList = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(instId, oriUserOrderInfo.getSysSeqNum());
        MchntOrderInfo oriMchntOrderInfo;
        if (oriMchntOrderInfoList == null || oriMchntOrderInfoList.isEmpty()) {
            rglog.error("原交易流水不存在");
            throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
        } else {
            oriMchntOrderInfo = oriMchntOrderInfoList.get(0);
        }
        rglog.debug("打印商户订单记录状态transStatus:<{}>,bizStatus<{}>", oriMchntOrderInfo.getTransStatus(), oriMchntOrderInfo.getBizStatus());
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO, oriMchntOrderInfo);

        /* Step3：校验订单状态 */
        if ("03".equals(oriUserOrderInfo.getOrderStatus()) && "1".equals(oriUserOrderInfo.getTransStatus())) {
            if ("00".equals(oriUserOrderInfo.getBizStatus()) || "31".equals(oriUserOrderInfo.getBizStatus()) ||
                    "41".equals(oriUserOrderInfo.getBizStatus()) || "50".equals(oriUserOrderInfo.getBizStatus())) {
                if ("1".equals(oriMchntOrderInfo.getTransStatus())) {
                    if ("00".equals(oriMchntOrderInfo.getBizStatus()) || "31".equals(oriMchntOrderInfo.getBizStatus()) ||
                            "41".equals(oriMchntOrderInfo.getBizStatus()) || "50".equals(oriMchntOrderInfo.getBizStatus())) {
                        rglog.info("原交易状态正常，继续交易");
                        if ("Y".equals(oriMchntOrderInfo.getRealSettleFlag())) {
                            rglog.error("该商户实时清算，暂时不支持退款");
                            throw new BizException(RespCodeEnum.D0_NOT_SUPPORT.getRespCode(), RespCodeEnum.D0_NOT_SUPPORT.getRespDesc());
                        }
                    }
                } else {
                    rglog.error("原交易是失败交易");
                    throw new BizException(RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespCode(), RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespDesc());
                }
            } else if ("10".equals(oriUserOrderInfo.getBizStatus())) {
                rglog.error("原交易已撤销");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespDesc());
            } else if ("20".equals(oriUserOrderInfo.getBizStatus())) {
                rglog.error("原交易已冲正");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespDesc());
            } else if ("30".equals(oriUserOrderInfo.getBizStatus())) {
                rglog.error("原交易已退货");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespCode(), RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespDesc());
            } else {
                rglog.error("原交易状态异常");
                throw new BizException(RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespCode(), RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespDesc());
            }
        } else {
            rglog.error("原交易是失败交易");
            throw new BizException(RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespCode(), RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespDesc());
        }

        /* Step4：校验退款是否超出退款总金额 */
        String refundAmt = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TRANS_AMT);
        if ("31".equals(oriMchntOrderInfo.getBizStatus())) {
            if (AmountUtil.compare(oriMchntOrderInfo.getRealSettleAmt(), AmountUtil.addition(oriMchntOrderInfo.getRefundAmt(), refundAmt)) < 0) {
                rglog.error("累计退款金额超出总金额,订单金额<{}>,累计退款金额<{}>,退款金额<{}>", oriMchntOrderInfo.getRealSettleAmt(), oriMchntOrderInfo.getRefundAmt(), refundAmt);
                throw new BizException(RespCodeEnum.REFUND_AMT_OVER.getRespCode(), RespCodeEnum.REFUND_AMT_OVER.getRespDesc());
            }
        } else {
            if (AmountUtil.compare(oriMchntOrderInfo.getOrderAmt(), refundAmt) < 0) {
                rglog.error("退款金额超出总金额");
                throw new BizException(RespCodeEnum.REFUND_AMT_OVER.getRespCode(), RespCodeEnum.REFUND_AMT_OVER.getRespDesc());
            }
        }

        /* Step5：固定金额手续费退款时，当前退款金额+商户累计退款金额<= 商户结算净额(部分退款) */
        if ("2".equals(oriMchntOrderInfo.getFeeInputMode()) &&
                AmountUtil.compare(AmountUtil.addition(oriMchntOrderInfo.getRefundAmt(), refundAmt), oriMchntOrderInfo.getRealSettleAmt()) == -1 &&
                AmountUtil.compare(oriMchntOrderInfo.getMchntSettleAmt(), AmountUtil.addition(oriMchntOrderInfo.getRefundAmt(), refundAmt)) == -1) {
            rglog.error("商户为固定金额收取手续费，部分退款的累计退款金额<{}>加上此次退款金额<{}>大于商户结算净额<{}>,不允许退款", oriMchntOrderInfo.getRefundAmt(), refundAmt, oriMchntOrderInfo.getMchntSettleAmt());
            throw new BizException(RespCodeEnum.ORDER_CANT_REFUND.getRespCode(), RespCodeEnum.ORDER_CANT_REFUND.getRespDesc());
        }

        /* Step6：获取原支付订单信息 */
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, oriUserOrderInfo.getSysSeqNum());
        if (null == payOrderInfoList || payOrderInfoList.isEmpty()) {
            rglog.error("原交易支付订单查询为为空");
            throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
        }
        payOrderInfoList = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.UPWX.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.UPAL.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.NUWX.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.CUPS.getChannelType())
                || item.getMsgDstId().equals(ChannelEnum.NUAL.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.ESB.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.WXZF.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.ALIP.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.UPQC.getChannelType())).collect(Collectors.toList());
        if (payOrderInfoList.size() == 0) {
            rglog.error("原交易不存在支付订单信息,拒绝交易!,原用户订单信息:{}", JSON.toJSONString(oriUserOrderInfo));
            throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
        }
        PayOrderInfo oriPayOrderInfo = payOrderInfoList.get(0);
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO, oriPayOrderInfo);

        /* Step7：根据原系统流水号查询退款订单，判断是否存在退款中的订单,如果存在退款中的拒绝当前退款 */
        List<UserOrderInfo> userOrderInfoList = userOrderInfoMapper.selectUserOrderInfoByOrigSysSeqNum(instId, oriUserOrderInfo.getSysSeqNum());
        if (userOrderInfoList != null && userOrderInfoList.size() > 0) {
            Predicate<UserOrderInfo> transStat = item -> TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(item.getTransStatus());
            Predicate<UserOrderInfo> bizStat = item -> BizStatusEnum.PROCESSING.getStatus().equals(item.getBizStatus());
            userOrderInfoList = userOrderInfoList.stream().filter(transStat.or(bizStat)).collect(Collectors.toList());
            if (userOrderInfoList.size() > 0) {
                rglog.error("原商户订单号<>、系统流水号<{}>存在退款状态未确定，不允许退款", oriUserOrderInfo.getMchntOrderId(), userOrderInfoList.get(0).getSysSeqNum());
                throw new BizException(RespCodeEnum.ORDER_CANT_REFUND.getRespCode(), RespCodeEnum.ORDER_CANT_REFUND.getRespDesc());
            }
        }
    }

    @Override
    public void posPublicAuthComCheck() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);

        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("查询商户信息失败<{}>", mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /*原交易状态校验,获取原交易，退款根据渠道上送原流水号*/
        String authNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.AUTH_NO);
        UserOrderInfo oriUserOrderInfo;
        MchntOrderInfo oriMchntOrderInfo;
        PayOrderInfo oriPayOrderInfo;
        if (!StringUtil.isEmptyOrNull(authNo)) {
            rglog.info("通过原预授权交易授权码：<{}>获取相关原订单信息", authNo);
            /* 获取原支付订单表*/
            String payAcctNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.PAN);
            PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
            List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoByAcctNoAndAuthCode(instId, mchntNo, McpsTxnNumConstant.AUTH_TXN_NUM, payAcctNo, authNo);
            Optional<PayOrderInfo> payOrderInfoOpt = payOrderInfoList.stream().filter(item -> item.getBizStatus().equals(BizStatusEnum.AUTH_INCOMPLETE.getStatus())).findFirst();
            if (!payOrderInfoOpt.isPresent()) {
                rglog.debug("原交易未找到");
                throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
            } else {
                oriPayOrderInfo = payOrderInfoOpt.get();
                GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO, payOrderInfoOpt.get());
            }
            /* 获取原用户订单表 */
            UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
            oriUserOrderInfo = userOrderInfoMapper.selectUserOrderInfoByPrimaryKey(instId, payOrderInfoOpt.get().getSysSeqNum());
            if (null == oriUserOrderInfo) {
                rglog.debug("原交易未找到");
                throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
            }
            /* 判断订单状态 */
            if ("03".equals(oriUserOrderInfo.getOrderStatus()) && "1".equals(oriUserOrderInfo.getTransStatus())) {
                if ("40".equals(oriUserOrderInfo.getBizStatus())) {
                    /* 查询商户订单表，支付订单表判断放到业务层 */
                    MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
                    oriMchntOrderInfo = mchntOrderInfoMapper.selectMchntOrderInfoByPrimaryKey(instId, payOrderInfoOpt.get().getSysSeqNum(), mchntNo);
                    if (null == oriMchntOrderInfo) {
                        rglog.debug("商户订单表中不存在交易");
                        throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
                    }
                    if ("1".equals(oriMchntOrderInfo.getTransStatus())) {
                        if ("40".equals(oriMchntOrderInfo.getBizStatus())) {
                            rglog.info("原交易状态正常，继续交易");
                            GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_USER_ORDER_INFO, oriUserOrderInfo);
                            GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO, oriMchntOrderInfo);
                        }
                    } else {
                        rglog.debug("原交易是失败交易");
                        throw new BizException(RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespCode(), RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespDesc());
                    }
                } else if ("10".equals(oriUserOrderInfo.getBizStatus())) {
                    rglog.debug("原交易已撤销");
                    throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespDesc());
                } else if ("20".equals(oriUserOrderInfo.getBizStatus())) {
                    rglog.debug("原交易已冲正");
                    throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespDesc());
                } else if ("30".equals(oriUserOrderInfo.getBizStatus())) {
                    rglog.debug("原交易已退货");
                    throw new BizException(RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespCode(), RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespDesc());
                } else {
                    rglog.debug("原交易状态异常");
                    throw new BizException(RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespCode(), RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespDesc());
                }
            } else {
                rglog.debug("原交易是失败交易");
                throw new BizException(RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespCode(), RespCodeEnum.POS_ORIG_STATUS_FAIL.getRespDesc());
            }
        } else {
            rglog.debug("原交易授权码未上送");
            throw new BizException(RespCodeEnum.REQUEST_ERROR.getRespCode(), RespCodeEnum.REQUEST_ERROR.getRespDesc());
        }
        /* 判断卡号是否一致 */
        String cardNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.PAN);
        String payerAcctInfo = oriPayOrderInfo.getPayerAcctInfo();
        if (!payerAcctInfo.equals(cardNo)) {
            rglog.error("根据原支付订单付款方信息<{}>查判断此次使用卡号与原交易不一致，不允许进行撤销操作！", payerAcctInfo);
            throw new BizException(RespCodeEnum.POS_INVALID_REL_TXN.getRespCode(), RespCodeEnum.POS_INVALID_REL_TXN.getRespDesc());
        }
        /* 判断预授权完成是否超出时限 */
        String earDate = DateUtil.getFutureDay(-30);
        String oriDate = oriPayOrderInfo.getTxnDate();
        if (AmountUtil.compare(earDate, oriDate) == 1) {
            rglog.error("检查原交易信息,预授权完成日期超出时限！！orgTxnDate[{}]", oriPayOrderInfo.getTxnDate());
            throw new BizException(RespCodeEnum.POS_RSP_TIME_OUT.getRespCode(), RespCodeEnum.POS_RSP_TIME_OUT.getRespDesc());
        }
        /* 判断是否为同一终端 */
        if (!(oriMchntOrderInfo.getTermNo()).equals(xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_NO))) {
            rglog.error("根据原商户订单查询原终端号<{}>与此次交易终端号不一致，拒绝交易！", oriMchntOrderInfo.getTermNo());
            throw new BizException(RespCodeEnum.POS_INVALID_REL_TXN.getRespCode(), RespCodeEnum.POS_INVALID_REL_TXN.getRespDesc());
        }
        /* 预授权金额大于等于预授权完成金额,单位为元 */
        BigDecimal multiplyAmt = new BigDecimal(oriUserOrderInfo.getOrderAmt()).multiply(new BigDecimal("1.15"));
        String multiply = multiplyAmt.toString();
        if (!(multiply.compareTo(xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TRANS_AMT)) >= 0)) {
            rglog.error("根据原用户订单查询原预授权金额<{}> *1.15倍金额小于与此次交易预授权金额<{}>，拒绝交易！", oriMchntOrderInfo.getOrderAmt(), xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TRANS_AMT));
            throw new BizException(RespCodeEnum.POS_INVALID_AMT.getRespCode(), RespCodeEnum.POS_INVALID_AMT.getRespDesc());
        }
    }

    @Override
    public void posPublicCancelCheck(TxnInfo txnInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        String msgSrcId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID);
        String transChannelId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.CHANNEL_ID);

        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("商户<{}>信息不存在或者状态异常!", mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /* 原交易状态校验,获取原交易，退款根据渠道上送不同分别处理，渠道上送原请求流水号或者原商户订单号 */
        String oriTraceNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.ORI_TRACE_NO);
        if (null == oriTraceNo) {
            rglog.debug("未上送原支付请求流水或者原支付订单号");
            throw new BizException(RespCodeEnum.REQUEST_ERROR.getRespCode(), RespCodeEnum.REQUEST_ERROR.getRespDesc());
        }
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo oriUserOrderInfo = userOrderInfoMapper.selectUserOrderInfoByFrontSeqNum(instId, oriTraceNo, msgSrcId, transChannelId);
        if (null == oriUserOrderInfo) {
            rglog.debug("用户订单表中不存在交易 frontSeqNum:{}", oriTraceNo);
            throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
        }
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_USER_ORDER_INFO, oriUserOrderInfo);

        /* 查询商户订单表，支付订单表判断放到业务层 */
        MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        MchntOrderInfo oriMchntOrderInfo = mchntOrderInfoMapper.selectMchntOrderInfoByPrimaryKey(instId, oriUserOrderInfo.getSysSeqNum(), mchntNo);
        if (null == oriMchntOrderInfo) {
            rglog.debug("商户订单表中不存在交易");
            throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
        }
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO, oriMchntOrderInfo);

        /* D0商户不允许撤销 */
        if (AppParamConstant.YES.equals(oriMchntOrderInfo.getRealSettleFlag())) {
            rglog.debug("D0商户不允许撤销!");
            throw new BizException(RespCodeEnum.D0_NOT_SUPPORT.getRespCode(), RespCodeEnum.D0_NOT_SUPPORT.getRespDesc());
        }

        /* 判断订单状态 */
        if (OrderStatusEnum.FINISH.getStatus().equals(oriUserOrderInfo.getOrderStatus())
                && TransStatusEnum.TRANS_SUCC.getStatus().equals(oriUserOrderInfo.getTransStatus())) {
            if (BizStatusEnum.FINISH.getStatus().equals(oriUserOrderInfo.getBizStatus())
                    || BizStatusEnum.AUTH_COMPLETE.getStatus().equals(oriMchntOrderInfo.getBizStatus())
                    || BizStatusEnum.CONFIRM.getStatus().equals(oriMchntOrderInfo.getBizStatus())
                    || BizStatusEnum.AUTH_INCOMPLETE.getStatus().equals(oriUserOrderInfo.getBizStatus())) {
                if (McpsTxnNumConstant.AUTH_CANCEL_TXN_NUM.equals(txnInfo.getSrcTxnAuthCfg().getTxnNum()) &&
                        BizStatusEnum.AUTH_COMPLETE.getStatus().equals(oriUserOrderInfo.getBizStatus())) {
                    rglog.debug("原交易已预授权完成，不允许预授权撤销");
                    throw new BizException(RespCodeEnum.ORDER_CANT_CANCEL.getRespCode(), RespCodeEnum.ORDER_CANT_CANCEL.getRespDesc());
                }
                if (TransTypeEnum.CANCEL.equals(TransTypeEnum.getTransType(txnInfo.getSrcTxnAuthCfg().getTxnNum())) &&
                        TransTypeEnum.AUTH.equals(TransTypeEnum.getTransType(oriUserOrderInfo.getTxnNum()))) {
                    rglog.debug("原交易为授权类交易，不允进行消费撤销，只能进行预授权撤销");
                    throw new BizException(RespCodeEnum.ORDER_CANT_CANCEL.getRespCode(), RespCodeEnum.ORDER_CANT_CANCEL.getRespDesc());
                }
                rglog.info("原交易状态正常，可以继续交易");
                GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO, oriMchntOrderInfo);
            } else if ("10".equals(oriUserOrderInfo.getBizStatus())) {
                rglog.debug("原交易已撤销");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespDesc());
            } else if ("20".equals(oriUserOrderInfo.getBizStatus())) {
                rglog.debug("原交易已冲正");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespDesc());
            } else if ("30".equals(oriUserOrderInfo.getBizStatus())) {
                rglog.debug("原交易已退货");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespCode(), RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespDesc());
            } else {
                rglog.debug("原交易状态异常,bizStatus:<{}>为<{}>", oriUserOrderInfo.getBizStatus(), BizStatusEnum.getDescByStaus(oriUserOrderInfo.getBizStatus()));
                throw new BizException(RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespCode(), RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespDesc());
            }
        } else {
            rglog.debug("原交易状态异常,不支持撤销!transStatus:<{}>为<{}>;orderStatus:<{}>为<{}>",
                    oriMchntOrderInfo.getTransStatus(), TransStatusEnum.getTransStatusEnum(oriMchntOrderInfo.getTransStatus()),
                    oriUserOrderInfo.getOrderStatus(), OrderStatusEnum.getOrderStatusEnum(oriUserOrderInfo.getOrderStatus()));
            throw new BizException(RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespCode(), RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespDesc());
        }
        /* 获取原支付订单表 */
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, oriUserOrderInfo.getSysSeqNum());
        payOrderInfoList = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.UPWX.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.NUWX.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.UPAL.getChannelType())
                || item.getMsgDstId().equals(ChannelEnum.NUAL.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.ESB.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.CUPS.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.UPQC.getChannelType())).collect(Collectors.toList());
        PayOrderInfo oriPayOrderInfo = payOrderInfoList.get(0);
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO, oriPayOrderInfo);

        /* 根据原系统流水号查询撤销订单，判断是否存在撤销中的订单,如果存在撤销中的拒绝当前撤销交易 */
        List<UserOrderInfo> userOrderInfoList = userOrderInfoMapper.selectUserOrderInfoByOrigSysSeqNum(instId, oriUserOrderInfo.getSysSeqNum());
        if (userOrderInfoList != null && userOrderInfoList.size() > 0) {
            Predicate<UserOrderInfo> transStat = item -> TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(item.getTransStatus());
            Predicate<UserOrderInfo> bizStat = item -> BizStatusEnum.PROCESSING.getStatus().equals(item.getBizStatus());
            userOrderInfoList = userOrderInfoList.stream().filter(transStat.or(bizStat)).collect(Collectors.toList());
            if (userOrderInfoList.size() > 0) {
                rglog.error("原商户订单号<>、系统流水号<{}>存在撤销状态未确定，不允许撤销", oriUserOrderInfo.getMchntOrderId(), userOrderInfoList.get(0).getSysSeqNum());
                throw new BizException(RespCodeEnum.ORDER_CANT_CANCEL.getRespCode(), RespCodeEnum.ORDER_CANT_CANCEL.getRespDesc());
            }
        }

        /* 判断是否为同一终端 */
        if (!(oriMchntOrderInfo.getTermNo()).equals(xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_NO))) {
            rglog.error("根据原商户订单查询原终端号<{}>与此次交易终端号不一致，拒绝交易！", oriMchntOrderInfo.getTermNo());
            throw new BizException(RespCodeEnum.POS_INVALID_REL_TXN.getRespCode(), RespCodeEnum.POS_INVALID_REL_TXN.getRespDesc());
        }

        /* 判断卡号是否一致 */
        String payerAcctInfo = oriPayOrderInfo.getPayerAcctInfo();
        String pan = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.PAN);
        if (!StringUtil.isEmptyOrNull(pan) && !payerAcctInfo.equals(pan)) {
            rglog.error("根据原支付订单付款方信息<{}>查判断此次使用卡号与原交易不一致，不允许进行撤销操作！", payerAcctInfo);
            throw new BizException(RespCodeEnum.POS_INVALID_REL_TXN.getRespCode(), RespCodeEnum.POS_INVALID_REL_TXN.getRespDesc());
        }

        /* 判断是否为预授权撤销,预授权撤销可以隔日 */
        if (!(McpsTxnNumConstant.AUTH_CANCEL_TXN_NUM.equals(txnInfo.getSrcTxnAuthCfg().getTxnNum()))) {
            String currDate = DateUtil.getCurrentDate();
            if (!oriPayOrderInfo.getTxnDate().equals(currDate)) {
                rglog.error("检查原交易信息失败,撤销日期不一致orgTxnDate[{}]", oriPayOrderInfo.getTxnDate());
                throw new BizException(RespCodeEnum.POS_INVALID_REL_TXN.getRespCode(), RespCodeEnum.POS_INVALID_REL_TXN.getRespDesc());
            }
        }
    }

    @Override
    public void posPublicRevsalCheckService(TxnInfo txnInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String mchntNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.MCHNT_NO);
        String msgSrcId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID);
        String transChannelId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.CHANNEL_ID);

        MchntService mchntService = new MchntServiceImpl();
        MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
        if (null == mchntInfo) {
            rglog.error("商户<{}>信息不存在或者状态异常!", mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }

        /* 原交易状态校验,获取原交易，退款根据渠道上送不同分别处理，渠道上送原流水号或者原商户订单号 */
        String oriTraceNo = xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.ORI_TRACE_NO);
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo oriUserOrderInfo = userOrderInfoMapper.selectUserOrderInfoByFrontSeqNum(instId, oriTraceNo, msgSrcId, transChannelId);
        if (null == oriUserOrderInfo) {
            rglog.debug("用户订单表中不存在交易 frontSeqNum:{}", oriTraceNo);
            throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
        }
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_USER_ORDER_INFO, oriUserOrderInfo);

        /* 查询商户订单表，支付订单表判断放到业务层 */
        MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
        MchntOrderInfo oriMchntOrderInfo = mchntOrderInfoMapper.selectMchntOrderInfoByPrimaryKey(instId, oriUserOrderInfo.getSysSeqNum(), mchntNo);
        if (null == oriMchntOrderInfo) {
            rglog.debug("商户订单表中不存在交易");
            throw new BizException(RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespCode(), RespCodeEnum.POS_ORIG_TXN_NOT_FOUND.getRespDesc());
        }

        /* 判断订单状态 */
        if ((OrderStatusEnum.INIT.getStatus().equals(oriUserOrderInfo.getOrderStatus()) && TransStatusEnum.TRANS_TIMEOUT.getStatus().equals(oriUserOrderInfo.getTransStatus())) ||
                (OrderStatusEnum.FINISH.getStatus().equals(oriUserOrderInfo.getOrderStatus()) && TransStatusEnum.TRANS_SUCC.getStatus().equals(oriUserOrderInfo.getTransStatus()))) {
            if (BizStatusEnum.PROCESSING.getStatus().equals(oriUserOrderInfo.getBizStatus()) ||
                    BizStatusEnum.FINISH.getStatus().equals(oriUserOrderInfo.getBizStatus()) ||
                    BizStatusEnum.AUTH_INCOMPLETE.getStatus().equals(oriUserOrderInfo.getBizStatus()) ||
                    BizStatusEnum.AUTH_COMPLETE.getStatus().equals(oriUserOrderInfo.getBizStatus())) {
                if (TransTypeEnum.REVSAL.equals(TransTypeEnum.getTransType(txnInfo.getSrcTxnAuthCfg().getTxnNum())) &&
                        TransTypeEnum.AUTH.equals(TransTypeEnum.getTransType(oriUserOrderInfo.getTxnNum()))) {
                    rglog.debug("原交易为授权类交易，不允进行消费冲正，只能进行授权类冲正");
                    throw new BizException(RespCodeEnum.ORDER_CANT_REVSAL.getRespCode(), RespCodeEnum.ORDER_CANT_REVSAL.getRespDesc());
                }
                rglog.info("原交易状态超时或者成功，可以继续交易");
                GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_MCHNT_ORDER_INFO, oriMchntOrderInfo);
            } else if (BizStatusEnum.CANCEL.getStatus().equals(oriUserOrderInfo.getBizStatus())) {
                rglog.debug("原交易已撤销");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_CANCEL.getRespDesc());
            } else if (BizStatusEnum.REVSAL.getStatus().equals(oriUserOrderInfo.getBizStatus())) {
                rglog.debug("原交易已冲正");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespCode(), RespCodeEnum.POS_ORIG_ALREADY_REVSAL.getRespDesc());
            } else if (BizStatusEnum.REFUND.getStatus().equals(oriUserOrderInfo.getBizStatus())) {
                rglog.debug("原交易已退货");
                throw new BizException(RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespCode(), RespCodeEnum.POS_ORIG_ALREDY_REFUND.getRespDesc());
            } else {
                rglog.debug("原交易状态异常");
                throw new BizException(RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespCode(), RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespDesc());
            }
        } else {
            rglog.debug("原交易已是终态,不支持冲正!");
            throw new BizException(RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespCode(), RespCodeEnum.POS_ORIG_ORDER_STATUS_ERROR.getRespDesc());
        }

        /* 获取原支付订单表*/
        PayOrderInfoMapper payOrderInfoMapper = new PayOrderInfoMapperImpl();
        List<PayOrderInfo> payOrderInfoList = payOrderInfoMapper.selectPayOrderInfoBySysSeqNum(instId, oriUserOrderInfo.getSysSeqNum());
        payOrderInfoList = payOrderInfoList.stream().filter(item -> item.getMsgDstId().equals(ChannelEnum.UPWX.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.NUWX.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.UPAL.getChannelType())
                || item.getMsgDstId().equals(ChannelEnum.NUAL.getChannelType()) || item.getMsgDstId().equals(ChannelEnum.ESB.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.CUPS.getChannelType()) ||
                item.getMsgDstId().equals(ChannelEnum.UPQC.getChannelType())).collect(Collectors.toList());
        PayOrderInfo oriPayOrderInfo = payOrderInfoList.get(0);
        GlobalTransUtil.setCacheValue(TransCacheConstant.ORIG_PAY_ORDER_INFO, oriPayOrderInfo);

        /* 判断是否为同一终端 */
        if (!(oriMchntOrderInfo.getTermNo()).equals(xmlTreeUtil.getXmlTreeStringValue(McpsTreeNodeConstant.TERM_NO))) {
            rglog.error("根据原商户订单查询原终端号<{}>与此次交易终端号不一致，拒绝交易！", oriMchntOrderInfo.getTermNo());
            throw new BizException(RespCodeEnum.POS_INVALID_REL_TXN.getRespCode(), RespCodeEnum.POS_INVALID_REL_TXN.getRespDesc());
        }

        /* 判断是否为当天冲正 */
        String currDate = DateUtil.getCurrentDate();
        if (!oriPayOrderInfo.getTxnDate().equals(currDate)) {
            rglog.error("检查原交易信息失败,冲正日期不一致orgTxnDate[{}]", oriPayOrderInfo.getTxnDate());
            throw new BizException(RespCodeEnum.POS_INVALID_REL_TXN.getRespCode(), RespCodeEnum.POS_INVALID_REL_TXN.getRespDesc());
        }
    }

    private boolean verifyMchntSignString(String instId, String sign, String signBlock, String mchntNo) throws Exception {
        /*获取秘钥串*/
        MchntService mchntService = new MchntServiceImpl();
        MchntKeyInfo mchntKeyInfo = mchntService.getMchntKeyInfo(instId, mchntNo, "APPID", "00");
        if (null == mchntKeyInfo) {
            rglog.error("商户秘钥值为空:商户号{}", mchntNo);
            return false;
        }
        if (StringUtil.isEmptyOrNull(mchntKeyInfo.getKeyValue())) {
            rglog.error("商户秘钥值为空:商户号{}", mchntNo);
            return false;
        }
        String oriMd5Str = signBlock + "&sign_key=" + mchntKeyInfo.getKeyValue().trim();
        try {
            String md5SignStr = MD5Util.MD5Encode(oriMd5Str);
            if (null == md5SignStr) {
                rglog.error("商户Md5秘钥生成为空");
                return false;
            } else {
                return md5SignStr.equals(sign);
            }
        } catch (Exception e) {
            rglog.error("商户Md5秘钥生成异常:{}", e.getMessage());
            return false;
        }
    }
}
